package com.innerchic.mapper.resfind;

import android.view.View;

import androidx.annotation.ColorRes;
import androidx.annotation.IdRes;
import androidx.annotation.LayoutRes;
import androidx.appcompat.app.AppCompatActivity;

import com.innerchic.mapper.log.Logger;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * ================================================
 * 作    者：贾恒飞 >>> 17515250730@163.com
 * 项    目：young
 * 日    期：2021/11/2 9:30
 * 包    名：com.innerchic.mapper.resfind
 * 描    述：资源文件自动赋值
 * Create by zFox from AndroidStudio4.2
 * ================================================
 */
public class ResFind {
    private ResFind() {
    }

    private static final ResFind instance = new ResFind();

    public static ResFind getInstance() {
        return instance;
    }

    /**
     * id集合
     */
    private final Map<String, Integer> idMap = new HashMap<>();

    public @IdRes
    int findId(String idName) {
        Integer id = idMap.get(idName);
        if (id == null) return 0;
        return id;
    }

    /**
     * 颜色集合
     */
    private final Map<String, Integer> colorMap = new HashMap<>();

    public @ColorRes
    int findColor(String colorName) {
        Integer color = colorMap.get(colorName);
        if (color == null) return 0;
        return color;
    }

    /**
     * 布局集合
     */
    private final Map<String, Integer> layoutMap = new HashMap<>();

    public @LayoutRes
    int findLayout(String layoutName) {
        Integer layout = layoutMap.get(layoutName);
        if (layout == null) return 0;
        return layout;
    }

    /**
     * 查找资源类
     */
    public void find(AppCompatActivity activity) {
        if (activity == null) return;
        Class<? extends AppCompatActivity> activityClass = activity.getClass();
        Field[] declaredFields = activityClass.getDeclaredFields();
        for (Field view : declaredFields) {
            Find find = view.getAnnotation(Find.class);
            if (find != null) {
                String name = view.getName();
                int id = findId(name);
                if (id == 0) continue;
                try {
                    view.setAccessible(true);
                    view.set(activity, activity.findViewById(id));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                continue;
            }
            FindView findView = view.getAnnotation(FindView.class);
            if (findView != null) {
                int id = findId(findView.value());
                if (id == 0) continue;
                try {
                    view.setAccessible(true);
                    view.set(activity, activity.findViewById(id));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                continue;
            }
            FindRes findRes = view.getAnnotation(FindRes.class);
            if (findRes != null) {
                if (View.class.isAssignableFrom(view.getType())) {
                    //当前资源是View
                    int id = findId(findRes.value());
                    if (id == 0) continue;
                    try {
                        view.setAccessible(true);
                        view.set(activity, activity.findViewById(id));
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                } else if (View.class.isAssignableFrom(Integer.TYPE)) {
                    //颜色
                    int color = findColor(findRes.value());
                    if (color == 0) continue;
                    try {
                        view.setAccessible(true);
                        view.set(activity, activity.getResources().getColor(color));
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 自助绑定组件类
     */
    public void bind(AppCompatActivity activity) {
        if (activity == null) return;
        Class<? extends AppCompatActivity> cls = activity.getClass();
        Field[] views = cls.getDeclaredFields();
        for (Field view : views) {
            if (view.getAnnotation(NotFind.class) != null) continue;
            if (!View.class.isAssignableFrom(view.getType())) continue;
            try {
                int id = findId(view.getName());
                if (id != 0) {
                    view.setAccessible(true);
                    view.set(activity, activity.findViewById(id));
                }
            } catch (IllegalAccessException e) {
                Logger.e(e, "组件绑定时赋值失败,异常消息为:@-", e.getMessage());
            }
        }
    }

    public void bind(View about, Object withObject) {
        if (about == null || withObject == null) return;
        Class<?> cls = withObject.getClass();
        Field[] views = cls.getDeclaredFields();
        for (Field view : views) {
            if (view.getAnnotation(NotFind.class) != null) continue;
            if (!View.class.isAssignableFrom(view.getType())) continue;
            if (idMap.containsKey(view.getName())) {
                try {
                    int id = findId(view.getName());
                    if (id != 0) {
                        view.setAccessible(true);
                        view.set(withObject, about.findViewById(id));
                    }
                } catch (IllegalAccessException e) {
                    Logger.e(e, "View绑定时赋值失败,异常消息为:@-", e.getMessage());
                }
            }
        }
    }

    /**
     * 初始化方法
     * 请在初始化application时执行此方法
     *
     * @param nowPackageName 当前项目包名
     */
    public synchronized void init(String nowPackageName) {
        try {
            Class<?> rcl = Class.forName(nowPackageName + ".R");
            Class<?>[] classes = rcl.getClasses();
            //当前类所有res_id
            Logger.d(Arrays.toString(classes));
            //取id的值
            Class<?> idCls = null;
            for (Class<?> aClass : classes) {
                if (aClass.getName().contains("$id")) {
                    idCls = aClass;
                    break;
                }
            }
            if (idCls != null) {
                Field[] ids = idCls.getFields();
                for (Field id : ids) {
                    idMap.put(id.getName(), id.getInt(idCls));
                }
            } else {
                Logger.d("没找到id相对应的类");
            }
            //取id的值
            Class<?> colorCls = null;
            for (Class<?> aClass : classes) {
                if (aClass.getName().contains("$color")) {
                    colorCls = aClass;
                    break;
                }
            }
            if (colorCls != null) {
                Field[] colors = colorCls.getFields();
                for (Field color : colors) {
                    colorMap.put(color.getName(), color.getInt(idCls));
                }
            } else {
                Logger.d("没找到color相对应的类");
            }
            //取布局的值
            Class<?> layoutCls = null;
            for (Class<?> aClass : classes) {
                if (aClass.getName().contains("$layout")) {
                    layoutCls = aClass;
                    break;
                }
            }
            if (layoutCls != null) {
                Field[] layouts = layoutCls.getFields();
                for (Field layout : layouts) {
                    layoutMap.put(layout.getName(), layout.getInt(idCls));
                }
            } else {
                Logger.d("没找到layout相对应的类");
            }
        } catch (ClassNotFoundException | IllegalAccessException e) {
            Logger.e(e, "组件绑定时赋值失败,异常消息为:@-[@-]", e.getMessage(), e.getClass().getName());
        }
    }

}
